<template>
  <div ref="editorContainer" class="monaco-editor-container"></div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'
import 'monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution';
const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  language: {
    type: String,
    default: 'javascript'
  },
  theme: {
    type: String,
    default: 'vs-dark'
  },
  options: {
    type: Object,
    default: () => ({})
  }
})

const emit = defineEmits(['update:modelValue', 'change'])

const editorContainer = ref(null)
let editor = null

// 创建编辑器实例
const createEditor = () => {
  if (!editorContainer.value) return

  // 合并默认配置和传入的配置
  const defaultOptions = {
    language: props.language,
    theme: props.theme,
    automaticLayout: true,
    scrollBeyondLastLine: false,
    minimap: { enabled: false },
    fontSize: 14,
    lineHeight: 21,
    padding: { top: 16, bottom: 16 },
    fontFamily: '"JetBrains Mono", Consolas, "Courier New", monospace',
    tabSize: 2
  }

  editor = monaco.editor.create(editorContainer.value, {
    ...defaultOptions,
    ...props.options,
    value: props.modelValue
  })

  // 监听内容变化
  editor.onDidChangeModelContent(() => {
    const value = editor.getValue()
    emit('update:modelValue', value)
    emit('change', value)
  })
}

// 监听值的变化
watch(
  () => props.modelValue,
  (newValue) => {
    if (editor && newValue !== editor.getValue()) {
      editor.setValue(newValue)
    }
  }
)

// 监听语言变化
watch(
  () => props.language,
  (newValue) => {
    if (editor) {
      monaco.editor.setModelLanguage(editor.getModel(), newValue)
    }
  }
)

// 监听主题变化
watch(
  () => props.theme,
  (newValue) => {
    if (editor) {
      monaco.editor.setTheme(newValue)
    }
  }
)

onMounted(() => {
  createEditor()
})

onBeforeUnmount(() => {
  if (editor) {
    editor.dispose()
  }
})
</script>

<style scoped>
.monaco-editor-container {
  width: 100%;
  height: 100%;
  overflow: hidden;
}
</style>